a tool for shared writing and social publishing
at feature/analytics 90 lines 2.6 kB view raw
1import { z } from "zod"; 2import { makeRoute } from "../lib"; 3import type { Env } from "./route"; 4import { getConstellationBacklinks } from "app/lish/[did]/[publication]/[rkey]/getPostPageData"; 5import { getDocumentURL } from "app/lish/createPub/getPublicationURL"; 6import { 7 normalizeDocumentRecord, 8 normalizePublicationRecord, 9} from "src/utils/normalizeRecords"; 10 11export const get_document_interactions = makeRoute({ 12 route: "get_document_interactions", 13 input: z.object({ 14 document_uri: z.string(), 15 }), 16 handler: async ( 17 { document_uri }, 18 { supabase }: Pick<Env, "supabase">, 19 ) => { 20 let { data: document } = await supabase 21 .from("documents") 22 .select( 23 ` 24 data, 25 uri, 26 comments_on_documents(*, bsky_profiles(*)), 27 document_mentions_in_bsky(*), 28 documents_in_publications(publications(*)) 29 `, 30 ) 31 .eq("uri", document_uri) 32 .limit(1) 33 .single(); 34 35 if (!document) { 36 return { comments: [], quotesAndMentions: [], totalMentionsCount: 0 }; 37 } 38 39 const normalizedData = normalizeDocumentRecord( 40 document.data, 41 document.uri, 42 ); 43 44 const pub = document.documents_in_publications?.[0]?.publications; 45 const normalizedPubRecord = pub 46 ? normalizePublicationRecord(pub.record) 47 : null; 48 49 // Compute document URL for constellation lookup 50 let absoluteUrl = ""; 51 if (normalizedData) { 52 const postUrl = getDocumentURL( 53 normalizedData, 54 document.uri, 55 normalizedPubRecord, 56 ); 57 absoluteUrl = postUrl.startsWith("/") 58 ? `https://leaflet.pub${postUrl}` 59 : postUrl; 60 } 61 62 // Fetch constellation backlinks 63 const constellationBacklinks = absoluteUrl 64 ? await getConstellationBacklinks(absoluteUrl) 65 : []; 66 67 // Deduplicate constellation backlinks internally 68 const uniqueBacklinks = Array.from( 69 new Map(constellationBacklinks.map((b) => [b.uri, b])).values(), 70 ); 71 72 // Combine DB mentions and constellation backlinks, deduplicating by URI 73 const dbMentionUris = new Set( 74 document.document_mentions_in_bsky.map((m) => m.uri), 75 ); 76 const quotesAndMentions: { uri: string; link?: string }[] = [ 77 ...document.document_mentions_in_bsky.map((m) => ({ 78 uri: m.uri, 79 link: m.link, 80 })), 81 ...uniqueBacklinks.filter((b) => !dbMentionUris.has(b.uri)), 82 ]; 83 84 return { 85 comments: document.comments_on_documents, 86 quotesAndMentions, 87 totalMentionsCount: quotesAndMentions.length, 88 }; 89 }, 90});